<template>
  <el-select
    v-on="$listeners"
    v-bind="$attrs"
    :value="value"
    filterable
    :remote="false"
    @change="handleChange"
    style="width: 100%"
    :placeholder="this.request ? '请选择 或者搜索后选择' : '请选择'"
  >
    <el-option
      v-for="(item, index) in selectOptions"
      :key="index"
      :label="item[mapping.label]"
      :value="item[mapping.value]"
    ></el-option>
  </el-select>
</template>

<script>
export default {
  name: "BaseSelect",
  model: {
    prop: "value",
    event: "change"
  },
  props: {
    value: {
      type: [String, Number, Array, Boolean],
      default: ""
    },
    options: {
      type: Array,
      default: () => []
    },
    mapping: {
      type: Object,
      default: () => {
        return {
          value: "value",
          label: "label"
        }
      }
    },
    request: {
      type: Function
    },
    handleOptions: {
      type: Function
    },
    model: {
      type: Object
    },
    formType: {
      type: String,
      default: "default"
    },
    initOption: {
      type: Object
    }
  },
  data() {
    return {
      selectOptions: []
    }
  },
  watch: {
    options: {
      immediate: true,
      deep: true,
      handler(options) {
        this.selectOptions = options
        this.allOptionHelper()
      }
    },
    initOption: {
      immediate: true,
      deep: true,
      handler(options) {
        this.compareInitOptions(options)
      }
    }
  },
  methods: {
    handleFocus() {
      if (this.selectOptions.length) {
        return
      }
      this.getSelectOptions()
    },
    handleChange(val) {
      this.$emit("change", val)
      let [current] = this.selectOptions.filter(
        (item) => item[this.mapping.value] === val
      )
      this.$emit("select", current)
    },
    allOptionHelper() {
      let allOption = {
        [this.mapping.label]: "全部",
        [this.mapping.value]: ""
      }
      if (
        this.formType === "search" &&
        !this.selectOptions.filter(
          (item) => item[this.mapping.label] === "全部"
        ).length
      ) {
        this.selectOptions = [allOption, ...this.selectOptions]
      }
    },
    async getSelectOptions(value, isInit) {
      if (!this.request) {
        return
      }
      let { data = [] } = await this.request(value, this.model)

      if (this.handleOptions) {
        data = this.handleOptions(data)
      }
      this.selectOptions = data
      if (isInit && this.initOption) {
        this.compareInitOptions(this.initOption)
      }
      this.allOptionHelper()
    },
    remoteMethod(value) {
      this.getSelectOptions(value)
    },
    compareInitOptions(options) {
      if (options) {
        if (
          this.selectOptions.filter(
            (item) => item[this.mapping.value] === options[this.mapping.value]
          ).length === 0
        ) {
          this.selectOptions = [...this.selectOptions, options]
        }
      }
    }
  },
  created() {
    this.getSelectOptions(null, true)
  }
}
</script>
